package xj.toolkit.unit;

import javax.management.ObjectName;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jmx.export.MBeanExporter;

import xj.toolkit.ebus.unit.UnitGroupBooter;
import xj.toolkit.jmx.JMXInvoker;
import xj.toolkit.util.AppInfo;
import xj.toolkit.util.SimpleRegistry;

public class StcServer {
	private static final Logger LOG = LoggerFactory.getLogger(StcServer.class);
	private AbstractApplicationContext rootCtx;

	public StcServer() {
		AbstractApplicationContext appCtxLauncher = null;
		try {
			AbstractApplicationContext root = new ClassPathXmlApplicationContext(
					"unitrepo/xt/main/xtRoot.xml");

			UnitGroupBooter booter = (UnitGroupBooter) root
					.getBean(UnitGroupBooter.class);
			if (booter != null) {
				booter.setRootAppCtx(root);
			}
			SimpleRegistry rootRegistry = (SimpleRegistry) root
					.getBean(SimpleRegistry.class);
			if (rootRegistry != null) {
				rootRegistry.getOrCreateEntry("__root_spring_ctx", root);
			}
			appCtxLauncher = new ClassPathXmlApplicationContext(
					new String[] { "unitrepo/xt/main/appCtxLauncher.xml" },
					root);

			AppContextInitor initor = (AppContextInitor) appCtxLauncher
					.getBean(AppContextInitor.class);
			if (initor != null) {
				ApplicationContext appCtx = initor.getApplicationContext();
				if (booter != null) {
					booter.setRootAppCtx(appCtx);
				}
				if (rootRegistry != null) {
					rootRegistry.createEntryRemover("__root_spring_ctx").run();
					rootRegistry.getOrCreateEntry("__root_spring_ctx", appCtx);
				}
			}
			AbstractApplicationContext stcServerCtx = new ClassPathXmlApplicationContext(
					new String[] { "unitrepo/xt/main/xtServer.xml" }, root);

			AppInfo info = (AppInfo) stcServerCtx.getBean(AppInfo.class);

			MBeanExporter exporter = (MBeanExporter) stcServerCtx
					.getBean("booterExporter");

			exporter.registerManagedResource(stcServerCtx, new ObjectName(
					"xj.toolkit:name=rootCtx"));
			exporter.registerManagedResource(this, new ObjectName(
					"xj.toolkit:name=stcServer"));

			String buildTime = info.getBuildTime();
			
			LOG.info(info.getSpecificationTitle() + " Server ["
					+ info.getAppVersion() + "/" + buildTime + "] Started... ");

			this.rootCtx = stcServerCtx;
		} catch (Exception e) {
			LOG.error("Server Start Error: ", e);
			System.exit(-1);
		} finally {
			if (appCtxLauncher != null) {
				appCtxLauncher.close();
			}
			
		}
	}

	public void exit() {
		if (this.rootCtx != null) {
			this.rootCtx.close();
		}
		System.exit(0);
	}

	public static void main(String[] args) {
		if (args.length > 0) {
			AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(
					"unitrepo/xt/main/xtJmxInvoker.xml");

			JMXInvoker invoker = (JMXInvoker) ctx.getBean("jmxInvoker");
			invoker.executeWith(args);
			ctx.close();
			System.exit(0);
		} else {
			new StcServer();
		}
	}
}
